package com.tang4j.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tang4j.core.model.MenuContainer;
import com.tang4j.core.model.ResponseModel;
import com.tang4j.core.model.UserConfig;
import com.tang4j.core.model.UserDetails;
import com.tang4j.core.model.easyui.MenuBar;
import com.tang4j.core.model.easyui.SideMenu;
import com.tang4j.core.model.factory.ResponseModelFactory;
import com.tang4j.core.service.impl.AbstractServiceImpl;
import com.tang4j.core.support.http.HttpCode;
import com.tang4j.core.util.DataUtil;
import com.tang4j.core.validate.RegexType;
import com.tang4j.mapper.ThSysUserMapper;
import com.tang4j.model.ThSysNavigation;
import com.tang4j.model.ThSysRole;
import com.tang4j.model.factory.NavFactory;
import com.tang4j.model.factory.RoleFactory;
import com.tang4j.model.response.ThSysNavigationDto;
import com.tang4j.model.response.ThSysUserDto;
import com.tang4j.security.util.JwtTokenUtil;
import com.tang4j.service.ThSysNavigationService;
import com.tang4j.service.ThSysRoleService;
import com.tang4j.service.ThSysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author saber
 * @since 2019-11-12
 */
@Service
public class ThSysUserServiceImpl extends AbstractServiceImpl<ThSysUserMapper, ThSysUserDto> implements ThSysUserService {


    @Autowired
    private ThSysUserMapper thSysUserMapper;
    @Autowired
    private ThSysNavigationService navigationService;
    @Autowired
    private ThSysRoleService roleService;

    /**
     * 获取用户信息
     *
     * @param val 用户账号或者userId或者手机号码或者邮箱地址
     * @return SysUser
     */
    @Override
    public ThSysUserDto queryUser(@Nullable Serializable val) {

        String tempVal = String.valueOf(val);
        StringBuffer sb = new StringBuffer();
        if (Pattern.matches(RegexType.EMAIL.value(), tempVal)) {
            sb.append("t.email");
        } else if (Pattern.matches(RegexType.PHONE.value(), tempVal)) {
            sb.append("t.phone");
        } else {
            sb.append("t.english_login_id");
        }
        QueryWrapper<ThSysUserDto> wrapper = new QueryWrapper<>();
        wrapper.eq(sb.toString(), tempVal);
        List<ThSysUserDto> thSysUsers = thSysUserMapper.queryList(wrapper);
        if (thSysUsers != null && thSysUsers.size() != 0) {
            return thSysUserMapper.queryList(wrapper).get(0);
        }
        return null;
    }

    /**
     * 获取用户信息 根据token
     *
     * @return ThSysUserDto
     */
    @Override
    public ThSysUserDto queryByToken() {
        String account = JwtTokenUtil.getUsernameFromToken(JwtTokenUtil.getToken());
        return queryUser(account);
    }

    /**
     * 根据用户权限获取的所有菜单信息（根据token）
     */
    @Override
    public ResponseModel queryUserInfo() {

        //用户个人信息
        ThSysUserDto thSysUserDto = queryByToken();
        UserConfig userConfig = new UserConfig();
        if (thSysUserDto != null) {
            userConfig.setUserDetails(new UserDetails(thSysUserDto.getId(), thSysUserDto.getEnglishLoginId(), thSysUserDto.getName()));
            //nav
            List<ThSysNavigation> navList = navigationService.queryList(new QueryWrapper<>());
            //nav主菜单
            List<SideMenu> sideMenuList = new ArrayList<>();
            List<MenuBar> menuBarList = new ArrayList<>();
            if (navList != null && navList.size() != 0) {
                //菜单分组
                Map<String, List<ThSysNavigation>> navMap = navList.stream().
                        collect(Collectors.groupingBy(ThSysNavigation::getPcode));

                //过滤出sideMenu最上级菜单
                navMap.forEach((k, v) -> {
                    if (k.contains("bar_base_manage")) {
                        sideMenuList.addAll(NavFactory.createEasyUISideMenuList(v));
                    }
                });
                //过滤出MenuBar最上级菜单
                navMap.forEach((k, v) -> {
                    if (k.contains("bar")) {
                        menuBarList.addAll(NavFactory.createEasyUIMenuBarList(v));
                    }
                });
                //加载sideMenu下级菜单信息
                navMap.forEach((k, v) -> sideMenuList.forEach(mainMenu -> {
                    if (mainMenu.getCode().equals(k)) {
                        mainMenu.setChildren(NavFactory.createEasyUISideMenuList(v));
                    }
                }));
                //加载MenuBar下级菜单信息
                navMap.forEach((k, v) -> menuBarList.forEach(mainMenu -> {
                    if (mainMenu.getCode().equals(k)) {
                        mainMenu.setChildren(NavFactory.createEasyUIMenuBarList(v));
                    }
                }));
                userConfig.setMenuContainer(new MenuContainer().
                        setSideMenuList(sideMenuList).setMenuBarList(menuBarList));
            }
            //role
            List<ThSysRole> roleList = roleService.queryByAccount(thSysUserDto.getEnglishLoginId());
            userConfig.setRoles(RoleFactory.createRoleList(roleList));
            return ResponseModelFactory.OKWithData(userConfig);
        } else {
            return ResponseModelFactory.createByHttpCode(HttpCode.NOT_FOUND);
        }
    }

    /**
     * 根据用户权限获取的顶部菜单信息（根据token）
     */
    @Override
    public ResponseModel selectWorkFlowManageInfo() {
        //用户个人信息
        ThSysUserDto thSysUserDto = queryByToken();
        UserConfig userConfig = new UserConfig();
        if (thSysUserDto != null) {
            userConfig.setUserDetails(new UserDetails(thSysUserDto.getId(), thSysUserDto.getEnglishLoginId(), thSysUserDto.getName()));
            //bar
            ThSysNavigationDto navigationDto = new ThSysNavigationDto();
            navigationDto.setUserId(thSysUserDto.getId());
            navigationDto.setPcode("bar");
            List<ThSysNavigation> navList = navigationService.selectByUserIdAndKey(navigationDto);
            userConfig.setMenuContainer(new MenuContainer().
                    setMenuBarList(NavFactory.createEasyUIMenuBarList(navList)));
            //role
            List<ThSysRole> roleList = roleService.queryByAccount(thSysUserDto.getEnglishLoginId());
            userConfig.setRoles(RoleFactory.createRoleList(roleList));
            return ResponseModelFactory.OKWithData(userConfig);
        } else {
            return ResponseModelFactory.createByHttpCode(HttpCode.NOT_FOUND);
        }
    }

    /**
     * 获取用户权限（根据token）
     */
    @Override
    public ResponseModel selectRolesView() {
        //用户个人信息
        try {
            String account = JwtTokenUtil.getUsernameFromToken(JwtTokenUtil.getToken());
            if (account != null) {
                List<ThSysRole> roleList = roleService.queryByAccount(account);
                if (roleList != null) {
                    return ResponseModelFactory.OKWithData(roleList);
                } else {
                    return ResponseModelFactory.error("未获取到相关权限信息");
                }
            } else {
                return ResponseModelFactory.createByHttpCode(HttpCode.UNAUTHORIZED);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseModelFactory.error(e.getMessage());
        }

    }

    @Override
    public void updateUserDept(@NotNull String deptId, @NotNull String userId) {
        ThSysUserDto userDto = this.selectById(userId);
        if (DataUtil.isEmpty(userDto.getDeptId())) {
            this.thSysUserMapper.insertUserDept(deptId, userId);
        } else {
            this.thSysUserMapper.updateUserDept(deptId, userId);
        }

    }


    @Override
    public ResponseModel resetPassword(String userId) {
        try {
            resetPasswordByUserId(userId);
            return ResponseModelFactory.OK();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseModelFactory.error(e.getMessage());
        }
    }

    @Override
    public List<ThSysUserDto> selectDeptUserList() {
        return this.thSysUserMapper.selectDeptUserList();
    }

    @Transactional(rollbackFor = Exception.class)
    public int resetPasswordByUserId(@NotNull String userId) {
        return this.thSysUserMapper.resetPassword(userId, new BCryptPasswordEncoder().encode("123456"));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserDept(ThSysUserDto thSysUserDto) {
        if (!DataUtil.isEmpty(thSysUserDto.getPassword())) {
            thSysUserDto.setPassword(new BCryptPasswordEncoder().encode(thSysUserDto.getPassword()));
        }
        ThSysUserDto userDto = this.update(thSysUserDto);
        if (!DataUtil.isEmpty(thSysUserDto.getDeptId()) && userDto != null && userDto.getId() != null) {
            updateUserDept(thSysUserDto.getDeptId(), userDto.getId());
        }

    }

}


